#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <dirent.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>

#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"

#include "mac_label.h"
#include "xKrnl_policystore.h"

#define MAX_LINE_LEN 1024

static unsigned char Buf[DIGEST_SIZE*32];

int xKrnl_policystore_init(void * sub_proc,void * para)
{
    int ret;

    return 0;
}

int xKrnl_policystore_start(void * sub_proc,void * para)
{
    int ret = 0, len = 0, i = 0, j = 0;
    int rc = 0;

    int type,subtype;	
	BYTE local_uuid[DIGEST_SIZE];	
    ret=proc_share_data_getvalue("uuid",local_uuid);
	if(ret<0)
		return ret;
    void * recv_msg;

    while(1)
    {
        usleep(time_val.tv_usec);

		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			continue;
		}
		else if((type==TYPE(MAC_LABEL))&&(subtype==SUBTYPE(MAC_LABEL,SUBJECT)))
		{
			ret=proc_add_subjectpolicy(sub_proc,recv_msg);
		}
		else if((type==TYPE(MAC_LABEL))&&(subtype==SUBTYPE(MAC_LABEL,OBJECT)))
		{
			ret=proc_add_objectpolicy(sub_proc,recv_msg);
		}
	}
    return 0;
}

int proc_add_subjectpolicy(void * sub_proc,void * recv_msg)
{
    int ret;
    int i=0;
	RECORD(MAC_LABEL,SUBJECT) * subject_list;
	RECORD(GENERAL_RETURN,STRING) * policy_notice;

    char policy_info[DIGEST_SIZE*4];
    do{
        ret = message_get_record(recv_msg,&subject_list,i++);
        if(ret<0)
            return -EINVAL;
        if(subject_list==NULL)
            break;
        memdb_store(subject_list,TYPE_PAIR(MAC_LABEL,SUBJECT),NULL);
    }while(1);       
    
    policy_notice = Talloc0(sizeof(*policy_notice));
    if(policy_notice ==NULL)
        return -EINVAL;
    policy_notice->name=dup_str("policy",0);
    Strcpy(policy_info,"subject:");
    Strcat(policy_info,"/boot/os_safe.d/subject.cfg");

    policy_notice->return_value=dup_str(policy_info,0);

    void * send_msg = message_create(TYPE_PAIR(GENERAL_RETURN,STRING),recv_msg);
    if(send_msg==NULL)
        return -EINVAL;
    message_add_record(send_msg,policy_notice);

    ex_module_sendmsg(sub_proc,send_msg);


    return 0; 
}

int proc_add_objectpolicy(void * sub_proc,void * recv_msg)
{
    int ret;
    int i=0;
	RECORD(MAC_LABEL,OBJECT) * object_list;
	RECORD(GENERAL_RETURN,STRING) * policy_notice;

    char policy_info[DIGEST_SIZE*4];

    // store all the object policy
    do{
        ret = message_get_record(recv_msg,&object_list,i++);
        if(ret<0)
            return -EINVAL;
        if(object_list==NULL)
            break;
        memdb_store(object_list,TYPE_PAIR(MAC_LABEL,OBJECT),NULL);
    }while(1);    

    policy_notice = Talloc0(sizeof(*policy_notice));
    if(policy_notice ==NULL)
        return -EINVAL;
    policy_notice->name=dup_str("policy",0);
    Strcpy(policy_info,"object:");
    Strcat(policy_info,"/boot/os_safe.d/object.cfg");

    policy_notice->return_value=dup_str(policy_info,0);

    void * send_msg = message_create(TYPE_PAIR(GENERAL_RETURN,STRING),recv_msg);
    if(send_msg==NULL)
        return -EINVAL;
    message_add_record(send_msg,policy_notice);

    ex_module_sendmsg(sub_proc,send_msg);
    return 0; 
}
